package com.zjxh.zjxh.common.exception;

import com.zjxh.zjxh.common.Result;
import com.zjxh.zjxh.common.constant.CMEnum;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

/**
 * @description:
 * @author: 公共异常
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

  @ExceptionHandler(value = CommonException.class)
  public Result<Object> commonException(CommonException e) {
    return Result.error(e);
  }

  @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
  public Result<Object> httpRequestMethodNotSupportedException(
      HttpRequestMethodNotSupportedException e) {
    return Result.error(CMEnum.ERROR_REQUEST_METHOD);
  }

  @ExceptionHandler(value = ConstraintViolationException.class)
  public Result<Object> constraintViolationException(ConstraintViolationException e) {
    return Result.error(
        CMEnum.ERROR_ARGS_VERIFY,
        StringUtils.join(
            e.getConstraintViolations().stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList()),
            "、"));
  }

  @ExceptionHandler(value = HttpMediaTypeNotSupportedException.class)
  public Result<Object> httpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
    return Result.error(CMEnum.ERROR_REQUEST_METHOD, "不支持的请求类型");
  }

  @ExceptionHandler(value = HttpMessageNotReadableException.class)
  public Result<Object> httpMessageNotReadableException(HttpMessageNotReadableException e) {
    return Result.error(CMEnum.ERROR_ARGS_VERIFY, "请求参数不合法");
  }

  @ExceptionHandler(value = MissingServletRequestParameterException.class)
  public Result<Object> missingServletRequestParameterException(
      MissingServletRequestParameterException e) {
    return Result.error(CMEnum.ERROR_ARGS_VERIFY);
  }

  @ExceptionHandler(value = MissingPathVariableException.class)
  public Result<Object> missingPathVariableException(MissingPathVariableException e) {
    return Result.error(CMEnum.ERROR_ARGS_VERIFY);
  }

  @ExceptionHandler(value = MethodArgumentNotValidException.class)
  public Result<Object> methodArgumentNotValidException(MethodArgumentNotValidException e) {
    return Result.error(
        CMEnum.ERROR_ARGS_VERIFY,
        StringUtils.join(
            e.getBindingResult().getFieldErrors().stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.toSet()),
            "、"));
  }

  @ExceptionHandler(value = BindException.class)
  public Result<Object> bindException(BindException e, HttpServletResponse response) {
    return Result.error(
        CMEnum.ERROR_ARGS_VERIFY,
        StringUtils.join(
            e.getBindingResult().getFieldErrors().stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.toSet()),
            "、"));
  }

  @ExceptionHandler(value = Exception.class)
  public Result<Object> exception(Exception e, HttpServletResponse response) {
    log.error("Catch Global Exception ------------------->> :", e);
    return Result.error(CMEnum.ERROR);
  }

  @ExceptionHandler(value = MaxUploadSizeExceededException.class)
  public Result<Object> maxUploadSizeExceededException(
      MaxUploadSizeExceededException e, HttpServletResponse response) {
    return Result.error(CMEnum.ERROR_ARGS_VERIFY, "文件过大");
  }
}
